home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / DependantScan.lha / DependantScan / Source / ProcessDirectory.c < prev    next >
C/C++ Source or Header  |  1998-06-05  |  8KB  |  158 lines

  1. #define DEF_PROCESSDIRECTORY_C
  2.  
  3. #include <exec/types.h>
  4. #include <dos/dos.h>
  5. #include <dos/dosasl.h>
  6. #include <clib/dos_protos.h>
  7. #include <clib/exec_protos.h>
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12.  
  13. #include "ProcessDirectory.h"
  14.  
  15. /*
  16.     int process_directory(
  17.         char *name,                                                                the name of the directory to examine (NULL - examine current directory)
  18.         char *pattern,                                                            pattern to search for (NULL - either the file pattern is in 'name' or use "#?")
  19.         int (*filefunc)(                                                        function to call when a file is encountered (NULL - dont' call any function)
  20.             struct AnchorPath *anchor,                                        the file to being processed
  21.             void *app_data),                                                    some data specific to this process
  22.         int (*dirfunc)(                                                        function to call when a directory is encountered (NULL - do root only)
  23.             struct AnchorPath *anchor,                                        the directory being processed
  24.             void *app_data),                                                    some data specific to this process
  25.        void *app_data)                                                        data to be passed to 'filefunc' and 'dirfunc'
  26.  
  27.    * Description
  28.        This function will examine all the files in the directory specified by 'name' and all the files in it's sub-directories (if 'dirfunc'
  29.        is non-NULL). For each file found, 'filefunc' will be called. If non-NULL, directories will be processed and each directory
  30.        encountered will cause a call to the 'dirfunc' function. The 'dirfunc' and 'filefunc' functions are normally return a 0. If these
  31.         function wish to stop the processing of the directory tree, they should return non-zero.
  32.  
  33.    * Return Value
  34.        0        = success
  35.        -1    = failure
  36.        other    = an error of some sort has occurred
  37. */
  38. int process_directory(
  39.     char *name,                                                                    /* the name of the directory to examine (NULL - examine current directory) */
  40.     char *pattern,                                                                /* pattern to search for (NULL - either the file pattern is in 'name' or use "#?") */
  41.     int (*filefunc)(                                                            /* function to call when a file is encountered (NULL - dont' call any function) */
  42.         struct AnchorPath *anchor,                                            /* the file to being processed */
  43.         void *app_data),                                                        /* some data specific to this process */
  44.     int (*dirfunc)(                                                            /* function to call when a directory is encountered (NULL - do root only) */
  45.         struct AnchorPath *anchor,                                            /* the directory being processed */
  46.         void *app_data),                                                        /* some data specific to this process */
  47.    void *app_data)                                                            /* data to be passed to 'filefunc' and 'dirfunc' */
  48. {
  49.     struct AnchorPath *anchor = NULL;                           /* the file/directory we are currently dealing with */
  50.     char *new_name = NULL;                                                    /* needed so that we can effectively alter 'name' */
  51.     BPTR previous_dir;                                                        /* the directory we were in before we switched */
  52.     int switch_back = 0;                                        /* true when we need to restore the current directory */
  53.     int retval = -1;                                                            /* assume an error condition */
  54.  
  55.     if ((pattern == NULL) && (name == NULL))                    /* if no pattern was supplied or there is no pattern in 'name' */
  56.         pattern = "#?";                                                        /* match all files */
  57.  
  58.     if (name == NULL)                                           /* if no name was supplied */
  59.     {
  60.         name = pattern;                                                        /* then search the current directory for 'pattern' */
  61.    }
  62.    else if (strlen(pattern))                                                /* if we have a pattern */
  63.    {
  64.        if ((new_name = AllocVec(PD_PATHMAX,0)) == NULL)            /* if we cannot get some memory for our revised name */
  65.            goto _ABORT;
  66.  
  67.       name = strcpy(new_name,name);                                        /* copy the supplied name to our new storage area and remember where that is */
  68.  
  69.        if ((name[strlen(name)-1] != ':') && (name[strlen(name)-1] != '/'))                                /* if the 'name' does not end in a directory separator */
  70.            strcat(name,"/");                                                    /* separate the name from the pattern */
  71.  
  72.       strcat(name,pattern);                                                /* put the pattern after the name */
  73.    }
  74.  
  75.     pattern = FilePart(name);                                                /* get the part of the spec that is the pattern */
  76.  
  77.     if ((anchor = AllocVec(sizeof(struct AnchorPath)+PD_PATHMAX,0)) == NULL)                            /* if we cannot get some memory for the file/directory we are currently dealing with */
  78.         goto _ABORT;
  79.  
  80.    anchor->ap_Strlen = PD_PATHMAX;                                        /* tell AmigaDOS how much space we have for the full path name */
  81.    anchor->ap_BreakBits = NULL;                                            /* we don't want to convience the user with the ability of aborting */
  82.  
  83.    if (MatchFirst(name,anchor) == 0)                                    /* if at least one file matches */
  84.    {
  85.       previous_dir = CurrentDir(anchor->ap_Current->an_Lock);  /* switch to the directory where these files may be found */
  86.         switch_back = 1;                                                        /* remember that we need to restore the current directory */
  87.  
  88.         do                                                                            /* process all the files that match */
  89.         {
  90.          if (anchor->ap_Info.fib_DirEntryType > 0)                    /* if this is a new directory */
  91.          {
  92.              if (dirfunc)                                                    /* if we have a function to process directories */
  93.              {
  94.                if ((retval = dirfunc(anchor,app_data)) != 0)   /* if there is an error when calling the application supplied function */
  95.                    goto _ABORT;                                            /* then we are done */
  96.  
  97.                     CurrentDir(previous_dir);                                /* switch back to where we came from */
  98.  
  99.                     anchor->ap_Buf[anchor->ap_Strlen-1] = '\0';        /* ensure that the full name is terminated */
  100. /* if we have difficulty scanning this directory with the same pattern */
  101.                     if ((retval = process_directory(anchor->ap_Buf,pattern,filefunc,dirfunc,app_data)) != 0)
  102.                         goto _ABORT;
  103.  
  104.                   previous_dir = CurrentDir(anchor->ap_Current->an_Lock);                          /* switch back to the directory we are processing */
  105.              }
  106.          }
  107.           else                                                  /* just a "plain file" */
  108.           {
  109.               if (filefunc)                                      /* if we have a function for processing files */
  110.               {
  111.                     if ((retval = filefunc(anchor,app_data)) != 0)  /* if we have a problem accessing this file */
  112.                         goto _ABORT;
  113.                 }
  114.           }
  115.         }
  116.         while (MatchNext(anchor) == 0);                          /* keep going while we have a matching file */
  117.     }
  118.  
  119.     if (IoErr() == ERROR_NO_MORE_ENTRIES)                       /* if we are here because no more files matched */
  120.         retval = 0;                                              /* that's OK */
  121.    else
  122.        retval = -1;                                                            /* we had a problem */
  123.  
  124. _ABORT:
  125.     if (switch_back)                                                            /* if we need to restore the current directory */
  126.         CurrentDir(previous_dir);                                            /* switch back to where we came from */
  127.  
  128.     if (new_name)                                               /* if we allocated some memory */
  129.       FreeVec(new_name);                                       /* then, clean up after ourselves */
  130.  
  131.     if (anchor)                                                                    /* if we have an anchor */
  132.     {
  133.         MatchEnd(anchor);                                                        /* free up any additional memory used by this anchor */
  134.         FreeVec(anchor);                                                        /* remove the anchor itself */
  135.     }
  136.  
  137.     return (retval);                                                            /* let caller know what happened */
  138. }
  139.  
  140. /*
  141.     int process_directory_do_nothing(
  142.         struct AnchorPath *anchor,                                            the directory currently being processed
  143.         void *app_data)                                                        data specific to this directory process
  144.  
  145.    * Description
  146.        This function can be used as one of the function pointer arguments to process_directory() when 1) You want to ignore everything except
  147.        sub-directory entries or 2) You want to recurse into sub-directories, but not process the directory entries themselves.
  148.  
  149.    * Return Value
  150.        0
  151. */
  152. int process_directory_do_nothing(
  153.     struct AnchorPath *anchor,                                                /* the directory currently being processed */
  154.     void *app_data)                                                            /* data specific to this directory process */
  155. {
  156.     return (0);
  157. }
  158.